package pt.iul.dcti.poo.financemanager;

import java.io.File;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import pt.iul.dcti.poo.financemanager.accounts.Account;
import pt.iul.dcti.poo.financemanager.accounts.StatementLine;
import pt.iul.dcti.poo.financemanager.accounts.formats.SimpleStatementFormat;
import pt.iul.dcti.poo.financemanager.categories.Category;
import pt.iul.dcti.poo.financemanager.date.Date;
import pt.iul.dcti.poo.utils.Menu;

public class PersonalFinanceManager {
	private static final String ACCOUNT_INFO = "account_info";
	private String[] listaFicheirosStrings;
	private ArrayList<File> listaFicheiros;
	private Account account;
	private LinkedList<Account> contas = new LinkedList<Account>();
	private SimpleStatementFormat formatoMovimentos= new SimpleStatementFormat();
	private List<Category> category = new ArrayList<Category>();

	public PersonalFinanceManager(){
		actualizarListaFicheiros();	
	}

	public void actualizarListaFicheiros(){
		File pasta = new File(ACCOUNT_INFO);
		listaFicheirosStrings = pasta.list();
		ArrayList<String> temp = new ArrayList<>();

		for(String a : pasta.list()){
			if(a.endsWith(".csv")){
				contas.add(Account.newAccount(new File("account_info/" +a)));
				temp.add(a);
			}
			else if(a.equals("Categories")) category = Category.readCategories("account_info/" +a);
		}
		listaFicheirosStrings = new String[temp.size()];
		for (int i = 0; i<temp.size(); i++) {
			listaFicheirosStrings[i] = temp.get(i);
		}
		List<StatementLine> movimentos = null;
		for(Account a : contas){
			for(int i = 0; i<a.getListaMovimentos().size();i++){
				movimentos = a.getListaMovimentos();
			}
		}
	}

	public String[] vectorNameAccounts(){
		String[] vector = new String[contas.size()];
		Account newC = null;
		for(int i = 0; i < contas.size(); i++){
			newC = contas.get(i);
			vector[i] = newC.getName();
		}
		return vector;
	}

	public void printStatements(String name){
		Account acc = null; 
		for(int i = 0; i < contas.size(); i++){
			acc = contas.get(i);
			if(String.valueOf(acc.getName()).equals(name)){
				List<StatementLine> stts = null;
				stts = acc.getListaMovimentos();
				for(int j = 0; j < stts.size(); j++){
					System.out.println(formatoMovimentos.format(stts.get(j)));

				}
			}
		}
		System.out.println(" ");
	}

	public void printTotalForMonth (String accountName) { 
		LinkedList<Date> monthsAndYearsAlreadyDone = new LinkedList<Date>();
		Account acc = null; 
		List <StatementLine> sttsList = new ArrayList<StatementLine>(); 
		int month = 0; 
		int year = 0; 
		int nextMonth = 0; 
		for (int i = 0; i < contas.size(); i++) { 
			acc = contas.get(i);
			if (acc.getName().equals(accountName)) { 
				sttsList = acc.getListaMovimentos(); 
				for (StatementLine statementLine : sttsList) {
					month = statementLine.getDate().getMonth().ordinal(); 
					year = statementLine.getDate().getYear(); 
					nextMonth = statementLine.getDate().getMonth().ordinal()+1; 
					//funçao para verificar se o mes e o ano não foi já contabilizado
					if(verifyNotAlreadyCounted(month, year, monthsAndYearsAlreadyDone) == true) { 
						if((month==12 && nextMonth==1) || nextMonth == (month+1)) { 
							System.out.println("Monthly total spent in " + month + "-" + year + " = " + acc.totalForMonth(month, year));
							// adiciona na lista temporaria
							monthsAndYearsAlreadyDone.add(new Date(0, month+1, year));
						} 
					}	
				}	
			} 
		} 
	}

	/**
	 * Esta função verifica se na lista temporária monthsAndYearsAlreadyDone este mês e ano não foi já contabilizado, se foi retorna falso, caso contrario retorna verdadeiro
	 * @param month
	 * @param year
	 * @param monthsAndYearsAlreadyDone
	 * @return
	 */
	private boolean verifyNotAlreadyCounted(int month, int year, LinkedList<Date> monthsAndYearsAlreadyDone) {
		for (Date date : monthsAndYearsAlreadyDone) {
			if(date.getMonth().ordinal() == month && date.getYear() == year)
				return false;
		}
		return true;
	}

	/*public void printTotalForMonth(String name){
		Account c = null;
		List<StatementLine> sttlProvisoria = new ArrayList<StatementLine>();
		List<StatementLine> sttl = new ArrayList<StatementLine>();
		for(int j = 0; j < contas.size(); j++){
			c = contas.get(j);
			if(String.valueOf(c.getName()).equals(name)){
				for(int y = 0; y < c.getListaMovimentos().size(); y++){
					sttl.add(c.getListaMovimentos().get(y));
				}
				for(int i = 0; i < sttl.size()-1; i++){
					if(sttl.get(i).getDate().getMonth() == sttl.get(i+1).getDate().getMonth() 
							&& sttl.get(i).getDate().getYear() == sttl.get(i+1).getDate().getYear()){
						sttlProvisoria.add(c.getListaMovimentos().get(i));
					}
				}
				for(int k = 0; k < sttlProvisoria.size(); k++){
					int month = sttlProvisoria.get(k).getDate().getMonth().ordinal();
					int year = sttlProvisoria.get(k).getDate().getYear();
					System.out.println("Monthly total spent in " + month + "-" + year + "=" + c.totalForMonth(month, year));
				}
			}
		}
	}*/

	/*public void printTotalForMonth(String name){	
		Account c = null;
		for(int j = 0; j < contas.size(); j++){
			c = contas.get(j);
			if(String.valueOf(c.getName()).equals(name)){
				List<StatementLine> sttl = null;
				sttl = c.getListaMovimentos();
				for(int y = 0; y < sttl.size()-1; y++){
					int month = sttl.get(y).getDate().getMonth().ordinal();
					int year = sttl.get(y).getDate().getYear();
					if(month != sttl.get(y+1).getDate().getMonth().ordinal()){
						System.out.println("Monthly total spent in " + month + "-" + year + "=" + c.totalForMonth(month, year));
					}
				}
			}
		}
		System.out.println(" ");
		}*/

	/*public void printTotalForMonth(String name){ 
		Account c = null; 
		for(int j = 0; j < contas.size(); j++){ 
			c = contas.get(j); 
			if(String.valueOf(c.getName()).equals(name)){ 
				List<StatementLine> sttl = null; 
				sttl = c.getListaMovimentos(); 
				for(int y = 0; y < sttl.size()-1; y++){ 
					int month = sttl.get(y).getDate().getMonth().ordinal(); 
					int year = sttl.get(y).getDate().getYear(); 
					if(y < sttl.size()) { 
						int mesSeguinte = sttl.get(y+1).getDate().getMonth().ordinal(); 
						if(mesSeguinte == (month+1) || (month==12 && mesSeguinte==1)) 
							System.out.println("Monthly total spent in " + month + "-" + year + "=" + c.totalForMonth(mesSeguinte, year)); 
					}else
						System.out.println("Monthly total spent in " + month + "-" + year + "=" + c.totalForMonth(month, year)); 
				} 
			} 
		} 
	}*/

	public List<File> devolverListaFicheiros(){
		return listaFicheiros;
	}

	public String[] getListaFicheirosStrings() {
		return listaFicheirosStrings;
	}

	public List<Category> listaCategory(){
		return category;
	}

	public void setListaFicheirosStrings(String[] listaFicheirosStrings) {
		this.listaFicheirosStrings = listaFicheirosStrings;
	}

	public LinkedList<Account> getContas() {
		return contas;
	}

	public void setContas(LinkedList<Account> contas) {
		this.contas = contas;
	}

	public void menuMovimentosContas(){
		Menu escolhaConta= new Menu();
		String[] OPTIONS_MOVIMENTOS = vectorNameAccounts();
		String name = escolhaConta.requestSelection("Contas", OPTIONS_MOVIMENTOS);
		printStatements(name);
	}

	public void menuPosicaoGlobal(){
		double totalBalance = 0;
		System.out.println("Global Position");
		System.out.println("Account Number \t Balance");
		for(int i = 0; i < getContas().size(); i++){
			long idAccount = getContas().get(i).getId();
			double valorBalance = getContas().get(i).currentBalance();
			totalBalance = totalBalance + valorBalance;
			System.out.println(idAccount + "\t" + valorBalance);
		}
		System.out.println("Total Balance " + totalBalance);
	}

	public void menuEvolucaoGlobalMes(){
		Menu escolhaConta= new Menu();
		String[] OPTIONS_MOVIMENTOS = vectorNameAccounts();
		String name = escolhaConta.requestSelection("Contas", OPTIONS_MOVIMENTOS);
		printTotalForMonth(name);
	}
}
